package com.power.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.power.constant.BusinessEnum;
import com.power.domain.MemberAddr;
import com.power.domain.Order;
import com.power.domain.OrderItem;
import com.power.domain.Sku;
import com.power.ex.handle.BussinessException;
import com.power.feign.OrderMemberFeign;
import com.power.feign.OrderProdFeign;
import com.power.mapper.OrderItemMapper;
import com.power.mapper.OrderMapper;
import com.power.model.OrderConfirmParam;
import com.power.model.Result;
import com.power.model.ShopOrder;
import com.power.service.OrderService;
import com.power.util.AuthUtils;
import com.power.vo.OrderStatusCount;
import com.power.vo.OrderVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author dingchunlin
* @description 针对表【order(订单表)】的数据库操作Service实现
* @createDate 2024-07-10 15:12:13
*/
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService{

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private OrderMemberFeign orderMemberFeign;

    @Autowired
    private OrderProdFeign orderProdFeign;


    /**
     * 分页查询订单列表
     * @param page        分页对象
     * @param orderNumber 订单号
     * @param status      订单状态
     * @param startTime   开始时间
     * @param endTime     结束时间
     * @return 订单分页对象
     */
    @Override
    public Page<Order> queryOrderPage(Page<Order> page, String orderNumber, Integer status, Date startTime, Date endTime) {
        // 首先查询出符合条件的订单
        page = orderMapper.selectPage(page,new LambdaQueryWrapper<Order>()
                .eq(ObjectUtil.isNotEmpty(status),Order::getStatus,status)
                .between(ObjectUtil.isAllNotEmpty(startTime,endTime),Order::getCreateTime,startTime,endTime)
                .eq(StringUtils.hasText(orderNumber),Order::getOrderNumber,orderNumber)
                .orderByDesc(Order::getCreateTime)
        );
        // 然后查询出订单项信息
        List<Order> orderList = page.getRecords();
        if (CollectionUtil.isEmpty(orderList) || orderList.size() == 0){
            return page;
        }
        // 获取订单号
        List<String> orderNumberList = orderList.stream().map(Order::getOrderNumber).collect(Collectors.toList());
        // 根据订单号查询订单详细信息
        List<OrderItem> orderItemList = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
                .in(OrderItem::getOrderNumber, orderNumberList));
        // 组装订单信息
        orderList.forEach(order -> {
            // 从订单详细中找到对应订单号的订单项
            List<OrderItem> itemList = orderItemList.stream()
                    .filter(orderItem -> orderItem.getOrderNumber().equals(order.getOrderNumber()))
                    .collect(Collectors.toList());
            order.setOrderItems(itemList);
        });
        return page;
    }

    /**
     * 根据订单号查询订单详情
     *
     * @param orderNumber 订单号
     * @return 订单详情
     */
    @Override
    public Order queryOrderDetailByOrderNumber(String orderNumber) {
        // 查询订单信息
        Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>()
               .eq(Order::getOrderNumber, orderNumber));
        // 查询订单详情
        List<OrderItem> orderItemList = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
               .eq(OrderItem::getOrderNumber, orderNumber));
        // 组装订单信息
        order.setOrderItems(orderItemList);
        // 从订单记录中获取收货标识
        Long addrOrderId = order.getAddrOrderId();
        // 远程调用：根据收货标识查询收货地址
        Result<MemberAddr> result = orderMemberFeign.getMemberAddrById(addrOrderId);
        if (BusinessEnum.OPERATION_FAIL.equals(result.getCode())) {
            throw new RuntimeException("远程接口调用失败，根据收货标识查询收货地址失败");
        }
        // 组装收货地址
        MemberAddr memberAddr = result.getData();
        order.setUserAddrOrder(memberAddr);
        // 根据openid查询用户信息
        Result<String> result1 = orderMemberFeign.getNickNameByOpenId(order.getOpenId());
        if (BusinessEnum.OPERATION_FAIL.equals(result1.getCode())) {
            throw new RuntimeException("远程接口调用失败，根据openid查询用户信息失败");
        }
        // 组装用户昵称
        order.setNickName(result1.getData());
        // 返回订单信息
        return order;
    }

    /**
     * 查询会员订单状态统计
     *
     * @return 会员订单状态统计
     */
    @Override
    public OrderStatusCount queryMemberOrderStatusCount() {
        // 获取会员的openid
        String openId = AuthUtils.getMemberOpenId();
        // 查询会员订单状态统计
        Long unPay = orderMapper.selectCount(new LambdaQueryWrapper<Order>()
                .eq(Order::getOpenId, openId)
                .eq(Order::getStatus, 1));
        Long payen = orderMapper.selectCount(new LambdaQueryWrapper<Order>()
                .eq(Order::getOpenId, openId)
                .eq(Order::getStatus, 2));
        Long consignment = orderMapper.selectCount(new LambdaQueryWrapper<Order>()
                .eq(Order::getOpenId, openId)
                .eq(Order::getStatus, 3));
        return new OrderStatusCount(unPay, payen, consignment);
    }

    /**
     * 分页查询会员订单列表
     * @param current 当前页
     * @param size    每页显示数量
     * @param status  订单状态
     * @return 会员订单分页对象
     */
    @Override
    public Page<Order> queryMemberOrderPage(Long current, Long size, Integer status) {
        // 获取会员的openid
        String openId = AuthUtils.getMemberOpenId();
        // 分页查询会员订单列表
        Page<Order> page = new Page<>(current, size);
        page = orderMapper.selectPage(page, new LambdaQueryWrapper<Order>()
               .eq(Order::getOpenId, openId)
               .eq(0 != status, Order::getStatus, status)
               .eq(Order::getDeleteStatus, 0)
               .orderByDesc(Order::getCreateTime));
        // 判断是否有值
        if (CollectionUtil.isEmpty(page.getRecords()) || page.getRecords().size() == 0){
            return page;
        }
        // 从订单集合中获取订单号集合
        List<String> orderNumberList = page.getRecords().stream().map(Order::getOrderNumber).collect(Collectors.toList());
        // 根据订单号集合查询订单详细信息
        List<OrderItem> orderItemList = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
               .in(OrderItem::getOrderNumber, orderNumberList));
        // 组装订单信息
        page.getRecords().forEach(order -> {
            // 从订单详细中找到对应订单号的订单项
            List<OrderItem> itemList = orderItemList.stream()
                    .filter(orderItem -> orderItem.getOrderNumber().equals(order.getOrderNumber()))
                    .collect(Collectors.toList());
            order.setOrderItemDtos(itemList);
        });
        return page;
    }

    /**
     * 根据订单号查询会员订单详情
     *
     * @param orderNumber 订单号
     * @return 会员订单详情
     */
    @Override
    public Order queryMemberOrderDetailByOrderNumber(String orderNumber) {
        // 根据订单号查询会员订单
        Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>()
               .eq(Order::getOrderNumber, orderNumber));
        // 判断订单是否存在
        if (ObjectUtil.isNull(order)){
            throw new BussinessException("订单编号有误，请检查后重试");
        }
        // 查询订单收货地址 远程调用
        Long addrOrderId = order.getAddrOrderId();
        Result<MemberAddr> result = orderMemberFeign.getMemberAddrById(addrOrderId);
        if (BusinessEnum.OPERATION_FAIL.getCode().equals(result.getCode())) {
            throw new RuntimeException("远程接口调用失败，根据收货标识查询收货地址失败");
        }
        // 组装收货地址
        MemberAddr memberAddr = result.getData();
        order.setUserAddrOrder(memberAddr);
        // 查询订单详情
        List<OrderItem> orderItemList = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
               .eq(OrderItem::getOrderNumber, orderNumber));
        // 组装订单详情
        order.setOrderItemDtos(orderItemList);
        return order;
    }

    /**
     * 确认收货
     * @param orderNumber 订单号
     * @return 是否成功
     */
    @Override
    public Boolean receiptMemberOrder(String orderNumber) {
        Order order = new Order();
        order.setUpdateTime(new Date());
        order.setFinallyTime(new Date());
        order.setStatus(5);
        return orderMapper.update(order, new LambdaQueryWrapper<Order>()
               .eq(Order::getOrderNumber, orderNumber)) > 0;
    }

    /**
     * 删除会员订单
     * @param orderNumber 订单号
     * @return 是否成功
     */
    @Override
    public Boolean removeMemberOrder(String orderNumber) {
        Order order = new Order();
        order.setDeleteStatus(1);
        order.setUpdateTime(new Date());
        return orderMapper.update(order, new LambdaQueryWrapper<Order>()
               .eq(Order::getOrderNumber, orderNumber)) > 0;
    }

    /**
     * 确认订单
     * @param orderConfirmParam 订单确认参数
     * @return 订单确认结果
     */
    @Override
    public OrderVo queryMemberOrderConfirmVo(OrderConfirmParam orderConfirmParam) {
        // 创建订单确认页面对象
        OrderVo orderVo = new OrderVo();
        // 获取会员的openid
        String openId = AuthUtils.getMemberOpenId();
        // 远程调用：根据openid查询会员默认收货地址
        Result<MemberAddr> result = orderMemberFeign.getMemberDefaultAddrByOpenId(openId);
         // 判断是否调用成功
        if (BusinessEnum.OPERATION_FAIL.getCode().equals(result.getCode())) {
            throw new RuntimeException("远程接口调用失败，根据openid查询会员默认收货地址失败");
        }
        // 获取用户的默认收货地址
        MemberAddr memberAddr = result.getData();
        orderVo.setMemberAddr(memberAddr);
        // 获取购物车id 集合
        List<Long> basketIds = orderConfirmParam.getBasketIds();
        // 判断请求来自哪里
        if (CollectionUtil.isEmpty(basketIds) || basketIds.size() == 0){
            // 购物车为空，请求来自商品详情
            productToCart(orderConfirmParam.getOrderItem(), orderVo);
        }else {
            // 请求来自购物车页面
        }

        return orderVo;
    }

    /**
     * 处理请求来自商品详情页面
     * @param orderItem
     * @param orderVo
     */
    private void productToCart(OrderItem orderItem, OrderVo orderVo) {
        // 创建订单店铺对象集合
        List<ShopOrder> shopOrderList = new ArrayList<>();
        // 创建订单店铺对象
        ShopOrder shopOrder = new ShopOrder();
        // 创建订单商品条目对象集合
        List<OrderItem> orderItemList = new ArrayList<>();

        // 获取商品skuId
        Long skuId = orderItem.getSkuId();
        // 远程调用：根据skuId查询商品sku对象
        Result<List<Sku>> result = orderProdFeign.getSkuListBySkuIds(Arrays.asList(skuId));
        // 判断是否调用成功
        if (BusinessEnum.OPERATION_FAIL.getCode().equals(result.getCode())) {
            throw new RuntimeException("远程接口调用失败，根据skuId查询商品sku对象失败");
        }
        // 获取商品sku对象
        List<Sku> skuList = result.getData();
        Sku sku = skuList.get(0);
        // 获取商品购买的数量
        Integer prodCount = orderItem.getProdCount();
        // 计算单个商品的总金额
        BigDecimal oneSkuTotalAmount = sku.getPrice().multiply(new BigDecimal(prodCount));

        // 给订单商品对象赋值
        orderItem.setShopId(orderItem.getShopId());
        orderItem.setCreateTime(new Date());
        orderItem.setCommSts(0);
        orderItem.setProductTotalAmount(oneSkuTotalAmount);
        // 将商品sku对象的属性复制给订单商品对象
        BeanUtils.copyProperties(sku, orderItem);

        orderItemList.add(orderItem);
        shopOrder.setShopId(orderItem.getShopId());
        shopOrder.setShopOrderItems(orderItemList);

        shopOrderList.add(shopOrder);
        // 补充信息
        orderVo.setShopCartOrders(shopOrderList);
        orderVo.setTotal(oneSkuTotalAmount);
        orderVo.setTotalCount(prodCount);
        orderVo.setActualTotal(oneSkuTotalAmount);
        if (oneSkuTotalAmount.compareTo(new BigDecimal(99)) == -1){
            orderVo.setTransfee(new BigDecimal(6));
            orderVo.setActualTotal(oneSkuTotalAmount.add(new BigDecimal(6)));
        }
    }
}




